﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once

#include "GcmpFoundation.h"
#include "GbmpTypeDefs.h"

namespace gcmp
{
    /// \brief 结构体Color用RGBA来表示颜色。
    ///
    /// 分别以R(red)、G(green)、B(blue)三个通道来进行描述，并以A(alpha)通道来标记透明度。
    /// 其中各通道范围: 
    ///     R: 0~255 
    ///     G: 0~255
    ///     B: 0~255
    ///     A: 0~255  其中'0'表示完全透明， '255'表示完全不透明
    struct GCMP_FOUNDATION_EXPORT Color
    {
        DEFINE_VISUAL_TYPE_UINT8(gcmp::IntBaseType::Hex)

        unsigned char R;
        unsigned char G;
        unsigned char B;
        unsigned char A; 

        /// \brief 构造函数, 默认为黑色，完全不透明
        Color() : R(0), G(0), B(0), A(0xff) 
        {}

        /// \brief 构造函数, 通过指定各颜色分量构造
        /// \param r  red分量
        /// \param g  green分量
        /// \param b  blue分量
        /// \param a  alpha分量, 默认完全不透明
        Color(unsigned char r, unsigned char g, unsigned char b, unsigned char a = 0xff) :
            R(r), G(g), B(b), A(a)
        {}


        /// \brief 创建一个默认颜色属性
        /// \return Color 一个默认的颜色属性，黑色不透明
        static Color Create() { return Color(); }

        /// \brief 通过指定R,G,B 三个通道的分量创建一个颜色属性，不透明
        /// \return Color 一个指定颜色分量的颜色色属性
        static Color CreateByRGB(unsigned char r, unsigned char g, unsigned char b) { return Color(r, g, b); }


        /// \brief 设置颜色属性的 red 分量
        /// \param r 需要设置的值
        /// \return bool 是否设置成功，true-成功，false-失败
        bool SetRed(unsigned char r) { R = r; return true; }

        /// \brief 设置颜色属性的 green 分量
        /// \param g 需要设置的值
        /// \return bool 是否设置成功，true-成功，false-失败
        bool SetGreen(unsigned char g) { G = g; return true; }
        
        /// \brief 设置颜色属性的 blue 分量
        /// \param b 需要设置的值
        /// \return bool 是否设置成功，true-成功，false-失败
        bool SetBlue(unsigned char b) { B = b; return true; }

        /// \brief 获取当前颜色的red分量
        /// \return unsigned char 当前颜色的red分量
        unsigned char GetRed() const { return R; }

        /// \brief 获取当前颜色的green分量
        /// \return unsigned char 当前颜色的green分量
        unsigned char GetGreen() const { return G; }

        /// \brief 获取当前颜色的blue分量
        /// \return unsigned char 当前颜色的量blue分量
        unsigned char GetBlue() const { return B; }

        /// \brief 颜色色值比较。
        ///
        /// r,g,b,a 中若有任一分量值小于传入颜色的分量值, 即视当前颜色色值小于传入颜色色值
        /// \param other 需要对比的颜色
        /// \return bool 比较结果
        bool IsLessThan(const Color& other) const { return *this < other; }
        
        /// \brief 判断两个颜色属性是否相同。
        ///
        /// r,g,b,a 中若有任一分量值与传入颜色的分量值不同, 即视当前两个颜色属性不相同
        /// \param other 需要对比的颜色
        /// \return bool 比较结果
        bool HasSameValue(const Color& other) const { return *this == other; }

        /// \brief 重载==操作符
        /// \param another 需要对比的颜色属性
        /// \param bool 对比结果
        bool operator == (const Color & another) const
        {
            if (this == &another)
            {
                return true;
            }

            return (R == another.R) && (G == another.G) && (B == another.B) && (A == another.A);
        }

        /// \brief 重载<操作符
        /// \param another 需要对比的颜色属性
        /// \param bool 对比结果
        bool operator < (const Color & another) const
        {
            if (R != another.R)
                return R < another.R;
            if (G != another.G)
                return G < another.G;
            if (B != another.B)
                return B < another.B;
            if (A != another.A)
                return A < another.A;
            return false;
        }

        /// \brief 重载!=操作符
        /// \param another 需要对比的颜色属性
        /// \param bool 对比结果
        bool operator != (const Color & another) const
        {
            return !(*this == another);
        }

        /// \brief 获取SmartColor配色
        ///
        /// \param colorForLight 浅色背景下的SmartColor配色, 传出参数
        /// \param colorForDark  深色背景下的SmartColor配色, 传出参数
        static void GetSmartColor(Color& colorForLight, Color& colorForDark);

        /// \brief  设置SmartColor配色
        ///
        /// 1） 默认为 浅色背景下为\see DarkBackGround， 深色背景下为 \see LightBackGround 可修改
        /// 2） 深浅背景以hsb颜色空间的B区进行区分， 亮度为51-100为浅背景， 0-50为深背景
        ///
        /// \param colorForLight 浅色背景下的SmartColor配色
        /// \param colorForDark  深色背景下的SmartColor配色
        static void SetSmartColor(const Color& colorForLight, const Color& colorForDark);

        /// \brief 黑白定义
        ///
        /// White(255, 255, 255)
        /// Black(0, 0, 0) 
        static const Color White;
        static const Color Black;

        /// \brief 色光三原色
        ///
        /// Red(255, 0, 0)
        /// Green(0, 255, 0)
        /// Blue(0, 0, 255)
        static const Color Red;
        static const Color Green;
        static const Color Blue;

        /// \brief 颜料三原色的色光表示
        ///
        /// Yellow(255, 255, 0)
        /// Magenta(255, 0, 255)
        /// Cyan(0, 255, 255)
        static const Color Yellow;
        static const Color Magenta;
        static const Color Cyan;

        /// \brief 其他颜色
        ///
        /// DarkSlateGray(47, 79, 79)
        /// Teal(0, 128, 128);
        /// PaleGodenrod(238, 232, 170);
        /// Orange(255, 165, 0);
        /// Sienna(160, 82, 45);
        /// FireBrick(178, 34, 34);
        /// Tan(210, 180, 140);
        /// SteelBlue(70, 130, 180);
        /// OliveDrab(85, 107, 47);
        /// Purple(128, 0, 128);
        static const Color DarkSlateGray;
        static const Color Teal;
        static const Color PaleGodenrod;
        static const Color Orange;
        static const Color Sienna;
        static const Color FireBrick;
        static const Color Tan;
        static const Color SteelBlue;
        static const Color OliveDrab;
        static const Color Purple;
        
        /// \brief 灰度颜色定义
        ///
        /// WhiteSmoke(245, 245, 245);
        /// GainSboro(220, 220, 220);
        /// LightGray(211, 211, 211);
        /// Silver(192, 192, 192);
        /// DarkGray(169, 169, 169);
        /// Gray(128, 128, 128);
        /// DimGray(105, 105, 105);
        static const Color WhiteSmoke;
        static const Color GainSboro;
        static const Color LightGray;
        static const Color Silver;
        static const Color DarkGray;
        static const Color Gray;
        static const Color DimGray;

        /// \brief 背景颜色
        ///
        /// 深色背景(25, 26, 28) 
        /// 浅色背景(230, 229, 227)
        /// 
        ///  可自定义修改
        static Color DarkBackGround;
        static Color LightBackGround;
    };
}

